package io.dcloud.player;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.pili.pldroid.player.AVOptions;
import com.pili.pldroid.player.PLMediaPlayer;
import com.pili.pldroid.player.widget.PLVideoTextureView;

import io.dcloud.player.utils.Utils;

/**
 * 视频播放
 * Created by lxy on 2017/4/20 21:26.
 */

public class PlayerFragment extends Fragment {

    private View mContentView;
    private View pb_loading;
    private PLVideoTextureView plv_player;
    private String rtmp = "";
    private Toast mToast = null;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        if (mContentView == null) {
            mContentView = inflater.inflate(getLayoutId(), null);
            onFragmentCreated(mContentView,savedInstanceState);
        } else {
            ViewGroup parent = (ViewGroup) mContentView.getParent();
            if (null != parent) {
                parent.removeAllViewsInLayout();
            }
        }
        return mContentView;
    }

    private int getLayoutId() {
        return R.layout.fragment_player;
    }

    private void onFragmentCreated(View contentView, Bundle savedInstanceState) {

        pb_loading = findView(R.id.pb_loading);
        plv_player = findView(R.id.plv_player);
        plv_player.setBufferingIndicator(pb_loading);
        options(AVOptions.MEDIA_CODEC_AUTO);
        plv_player.setOnCompletionListener(mOnCompletionListener);
        plv_player.setOnErrorListener(mOnErrorListener);
        plv_player.setOnPreparedListener(mOnPreparedListener);
        plv_player.setDisplayAspectRatio(PLVideoTextureView.ASPECT_RATIO_PAVED_PARENT);
    }

    private <V extends View> V findView(int id){
        return (V) mContentView.findViewById(id);
    }

    public void test2(){
        String rtmp = "rtmp://live.hkstv.hk.lxdns.com/live/hks";
        rtmp(rtmp);
    }
    public void test(){
        String rtmp = "rtmp://push.video.kujian.net/xindu/00000000000000003";
        rtmp(rtmp);
    }

    public void rtmp(String rtmp) {
        if(TextUtils.isEmpty(rtmp)) {
            rtmp = "rtmp://live.hkstv.hk.lxdns.com/live/hks";
        }
        this.rtmp = rtmp;
        plv_player.setVideoPath(this.rtmp);
        plv_player.start();
    }

    private void options(int codecType) {

        AVOptions options = new AVOptions();
        // 准备超时时间，包括创建资源、建立连接、请求码流等，单位是 ms
        // 默认值是：无
        options.setInteger(AVOptions.KEY_PREPARE_TIMEOUT, 10 * 1000);
        // 读取视频流超时时间，单位是 ms
        // 默认值是：10 * 1000
        options.setInteger(AVOptions.KEY_GET_AV_FRAME_TIMEOUT, 10 * 1000);
        options.setInteger(AVOptions.KEY_LIVE_STREAMING, 1);//直播
        options.setInteger(AVOptions.KEY_MEDIACODEC, codecType);
        // 是否自动启动播放，如果设置为 1，则在调用 `prepareAsync` 或者 `setVideoPath` 之后自动启动播放，无需调用 `start()`
        // 默认值是：1
        options.setInteger(AVOptions.KEY_START_ON_PREPARED, 0);

        plv_player.setAVOptions(options);
    }


    private PLMediaPlayer.OnErrorListener mOnErrorListener = new PLMediaPlayer.OnErrorListener() {
        @Override
        public boolean onError(PLMediaPlayer mp, int errorCode) {
            boolean isNeedReconnect = false;
            switch (errorCode) {
                case PLMediaPlayer.ERROR_CODE_INVALID_URI:
                    showToastTips("Invalid URL !");
                    break;
                case PLMediaPlayer.ERROR_CODE_404_NOT_FOUND:
                    showToastTips("404 resource not found !");
                    break;
                case PLMediaPlayer.ERROR_CODE_CONNECTION_REFUSED:
                    showToastTips("Connection refused !");
                    break;
                case PLMediaPlayer.ERROR_CODE_CONNECTION_TIMEOUT:
                    showToastTips("Connection timeout !");
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_EMPTY_PLAYLIST:
                    showToastTips("Empty playlist !");
                    break;
                case PLMediaPlayer.ERROR_CODE_STREAM_DISCONNECTED:
                    showToastTips("Stream disconnected !");
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_IO_ERROR:
                    showToastTips("Network IO Error !");
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_UNAUTHORIZED:
                    showToastTips("Unauthorized Error !");
                    break;
                case PLMediaPlayer.ERROR_CODE_PREPARE_TIMEOUT:
                    showToastTips("Prepare timeout !");
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_READ_FRAME_TIMEOUT:
                    showToastTips("Read frame timeout !");
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.ERROR_CODE_HW_DECODE_FAILURE:
                    options(AVOptions.MEDIA_CODEC_SW_DECODE);
                    isNeedReconnect = true;
                    break;
                case PLMediaPlayer.MEDIA_ERROR_UNKNOWN:
                    break;
                default:
                    showToastTips("unknown error !");
                    break;
            }
            // Todo pls handle the error status here, reconnect or call finish()
            if (isNeedReconnect) {
                sendReconnectMessage();
            }
            // Return true means the error has been handled
            // If return false, then `onCompletion` will be called
            return true;
        }
    };

    private PLMediaPlayer.OnCompletionListener mOnCompletionListener = new PLMediaPlayer.OnCompletionListener() {
        @Override
        public void onCompletion(PLMediaPlayer plMediaPlayer) {
        }
    };
    private PLMediaPlayer.OnPreparedListener mOnPreparedListener = new PLMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(PLMediaPlayer plMediaPlayer) {
            System.out.println("---onPrepared---");
            showToastTips("---onPrepared---");
        }
    };

    private void showToastTips(final String tips) {
        this.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (mToast != null) {
                    mToast.cancel();
                }
                mToast = Toast.makeText(PlayerFragment.this.getContext(), tips, Toast.LENGTH_SHORT);
                mToast.show();
                Log.i("PlayerFragment",tips);
            }
        });
    }

    private void sendReconnectMessage() {
        showToastTips("正在重连...");
        pb_loading.setVisibility(View.VISIBLE);
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MESSAGE_ID_RECONNECTING), 500);
    }

    private static final int MESSAGE_ID_RECONNECTING = 0x01;
    protected Handler mHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what != MESSAGE_ID_RECONNECTING) {
                return;
            }
            if (!Utils.isNetworkAvailable(getContext())) {
                sendReconnectMessage();
                return;
            }
            plv_player.setVideoPath(rtmp);
            plv_player.start();
        }
    };


    @Override
    public void onPause() {
        super.onPause();
        if (plv_player != null) {
            plv_player.pause();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (plv_player != null)
            plv_player.start();
    }

    @Override
    public void onDestroy() {

        if (plv_player != null) {
            plv_player.pause();
            plv_player.stopPlayback();
        }
        super.onDestroy();

    }


}
